<?php
namespace WDB\Analyzer;
use WDB;

/**
 *
 * @author Richard Ejem <richard(at)ejem.cz>
 * @package WDB
 *
 */
class TableView extends WDB\BaseObject implements iTable
{
    /** @var string*/
    protected $name;

    /** @var iSchema*/
    protected $schema;

    /** @var \WDB\Structure\TableColumns $tableColumns */
    protected $tableColumns;

    /** @var WDB\Annotation\Reflection */
    protected $annotations;

    /**
     *
     * @param string table name
     * @param string table comment (search for annotations)
     * @param WDB\Analyzer\Schema table schema
     * @param WDB\SQLDriver\iSQLDriver SQL driver to get table structure
     */
    public function __construct($tableName, $tableComment, WDB\Analyzer\iSchema $schema, WDB\SQLDriver\iSQLDriver $driver)
    {
        $this->name = $tableName;
        $this->schema = $schema;
        $this->tableColumns = $driver->getTableColumns($this);
        $this->annotations = WDB\Annotation\Reflection::fromString($tableComment);
        $this->annotations->mergeNeonWheel($schema->getModel(), $this->name);
        if (($c = $this->getWrapperClass()) !== NULL)
        {
            $refl = new \ReflectionClass($c);
            $this->annotations->merge($refl->getDocComment());
        }
    }

    public function onSchemaConstructed()
    {
    }

    // <editor-fold defaultstate="collapsed" desc="iTable implementation">
    public function getName()
    {
        return $this->name;
    }

    public function getIdentifier()
    {
        return new WDB\Query\Element\TableIdentifier($this->name, $this->schema->name);
    }

    public function getTitle()
    {
        return isset($this->annotations->title) ? $this->annotations->last('title')->text : $this->name;
    }


    public function getWrapperClass()
    {
        if (isset($this->annotations->wrapper))
        {
            return WDB\Utils\System::findClass($this->annotations->last('wrapper')->text, WDB\Config::read('userWrappersClassPrefix'));
        }
        return NULL;
    }
    public function getRecordWrapperClass()
    {
        if (isset($this->annotations->recordWrapper))
        {
            return WDB\Utils\System::findClass($this->annotations->last('recordWrapper')->text, WDB\Config::read('userWrappersClassPrefix'));
        }
        return NULL;
    }
    public function getWebUIClass()
    {
        if (isset($this->annotations->webUI))
        {
            return $this->annotations->last('webUI')->text;
        }
        return NULL;
    }

    public function getSchema()
    {
        return $this->schema;
    }

    public function getColumns()
    {
        return $this->tableColumns->columns;
    }
    public function getPrimaryKey()
    {
        $key = $this->tableColumns->primary;

        //primary key not present, try to find non-null unique key
        if (count($key) == 0)
        {
            $ukeys = $this->getUniqueKeys();
            foreach ($ukeys as $ukey)
            {
                if (count($ukey) > 0)
                {
                    //unique key found, check that all its fields are non-null
                    foreach ($ukey as $keyitem)
                    {
                        if ($this->tableColumns->columns[$keyitem]->isNullable())
                            continue;
                    }
                    $key = $ukey;
                    break;
                }
            }
            //no suitable unique key found, use all column
            if (count($key) == 0)
            {
                foreach ($this->tableColumns->columns as $column)
                {
                    $key[] = $column->getName();
                }
            }
        }
        return $key;
    }
    public function getUniqueKeys()
    {
        return $this->tableColumns->unique;
    }

    public function getForeignKeys()
    {
        return array();
    }

    public function fetchValidators(WDB\Event\Event $event)
    {
        foreach ($this->tableColumns->unique as $name=>$ukey)
        {
            if ($ukey != $this->tableColumns->primary)
            {
                foreach($ukey as &$val)
                {
                    $val = array('recName'=>$val, 'ColumnIdentifier'=> WDB\Query\Element\ColumnIdentifier::create($val, $this->name, $this->schema->getName()));
                }
                unset($val);
                $event->addListener(new WDB\Validation\UniqueConstraint($name, $ukey));
            }
        }
    }

    public function getDisplayDefault()
    {
        $a = array();
        foreach ($this->annotations->displayDefault as $val)
        {
            $a[] = $val->getText();
        }
        return $a;
    }

    public function getAnnotations()
    {
        return $this->annotations;
    }

    public function isListedInSchemaAdmin()
    {
        return $this->isWebUIAccessible() && !isset($this->annotations->nodisplay);
    }

    public function isWebUIAccessible()
    {
        return !isset($this->annotations->noaccess);
    }

    public function isUIDetail()
    {
        return true;
    }

    public function isUIEdit()
    {
        return true;
    }

    public function isUIDelete()
    {
        return true;
    }

    // </editor-fold>
}
